<!DOCTYPE html>
<!-- saved from url=(0118)http://roguebasin.roguelikedevelopment.org/index.php?title=Complete_Roguelike_Tutorial,_using_python%2Blibtcod,_part_6 -->
<html lang="en" dir="ltr" class="client-js"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Complete Roguelike Tutorial, using python+libtcod, part 6 - RogueBasin</title>
<meta charset="UTF-8">
<meta name="generator" content="MediaWiki 1.19.2">
<link rel="shortcut icon" href="http://roguebasin.roguelikedevelopment.org/favicon.ico">
<link rel="search" type="application/opensearchdescription+xml" href="http://roguebasin.roguelikedevelopment.org/opensearch_desc.php" title="RogueBasin (en)">
<link rel="EditURI" type="application/rsd+xml" href="http://roguebasin.roguelikedevelopment.org/api.php?action=rsd">
<link rel="alternate" type="application/atom+xml" title="RogueBasin Atom feed" href="http://roguebasin.roguelikedevelopment.org/index.php?title=Special:RecentChanges&feed=atom">
<link rel="stylesheet" href="http://roguebasin.roguelikedevelopment.org/load.php?debug=false&lang=en&modules=mediawiki.legacy.commonPrint%2Cshared%7Cskins.monobook&only=styles&skin=monobook&*">
<!--[if IE 6]><link rel="stylesheet" href="/skins/monobook/IE60Fixes.css?303" media="screen" /><![endif]-->
<!--[if IE 7]><link rel="stylesheet" href="/skins/monobook/IE70Fixes.css?303" media="screen" /><![endif]--><style type="text/css" media="all">.js-messagebox{margin:1em 5%;padding:0.5em 2.5%;border:1px solid #ccc;background-color:#fcfcfc;font-size:0.8em}.js-messagebox .js-messagebox-group{margin:1px;padding:0.5em 2.5%;border-bottom:1px solid #ddd}.js-messagebox .js-messagebox-group:last-child{border-bottom:thin none transparent}

/* cache key: 133099-basin:resourceloader:filter:minify-css:7:8b08bdc91c52a9ffba396dccfb5b473c */


.mw-collapsible-toggle{float:right} li .mw-collapsible-toggle{float:none} .mw-collapsible-toggle-li{list-style:none}

/* cache key: 133099-basin:resourceloader:filter:minify-css:7:4250852ed2349a0d4d0fc6509a3e7d4c */
</style><meta name="ResourceLoaderDynamicStyles" content="">
<link rel="stylesheet" href="http://roguebasin.roguelikedevelopment.org/load.php?debug=false&lang=en&modules=site&only=styles&skin=monobook&*">
<style>a:lang(ar),a:lang(ckb),a:lang(fa),a:lang(kk-arab),a:lang(mzn),a:lang(ps),a:lang(ur){text-decoration:none}a.new,#quickbar a.new{color:#ba0000}

/* cache key: 133099-basin:resourceloader:filter:minify-css:7:c88e2bcd56513749bec09a7e29cb3ffa */
</style>

<script src="./Complete Roguelike Tutorial, using python+libtcod, part 6 - RogueBasin_files/load.php"></script><style type="text/css"></style><script src="./Complete Roguelike Tutorial, using python+libtcod, part 6 - RogueBasin_files/load(1).php"></script>
<script>if(window.mw){
mw.config.set({"wgCanonicalNamespace":"","wgCanonicalSpecialPageName":false,"wgNamespaceNumber":0,"wgPageName":"Complete_Roguelike_Tutorial,_using_python+libtcod,_part_6","wgTitle":"Complete Roguelike Tutorial, using python+libtcod, part 6","wgCurRevisionId":30253,"wgArticleId":3806,"wgIsArticle":true,"wgAction":"view","wgUserName":null,"wgUserGroups":["*"],"wgCategories":["Developing"],"wgBreakFrames":false,"wgPageContentLanguage":"en","wgSeparatorTransformTable":["",""],"wgDigitTransformTable":["",""],"wgRelevantPageName":"Complete_Roguelike_Tutorial,_using_python+libtcod,_part_6","wgRestrictionEdit":[],"wgRestrictionMove":[]});
}</script><script>if(window.mw){
mw.loader.implement("user.options",function($){mw.user.options.set({"ccmeonemails":0,"cols":80,"date":"default","diffonly":0,"disablemail":0,"disablesuggest":0,"editfont":"default","editondblclick":0,"editsection":1,"editsectiononrightclick":0,"enotifminoredits":0,"enotifrevealaddr":0,"enotifusertalkpages":1,"enotifwatchlistpages":0,"extendwatchlist":0,"externaldiff":0,"externaleditor":0,"fancysig":0,"forceeditsummary":0,"gender":"unknown","hideminor":0,"hidepatrolled":0,"highlightbroken":1,"imagesize":2,"justify":0,"math":1,"minordefault":0,"newpageshidepatrolled":0,"nocache":0,"noconvertlink":0,"norollbackdiff":0,"numberheadings":0,"previewonfirst":0,"previewontop":1,"quickbar":5,"rcdays":7,"rclimit":50,"rememberpassword":0,"rows":25,"searchlimit":20,"showhiddencats":0,"showjumplinks":1,"shownumberswatching":1,"showtoc":1,"showtoolbar":1,"skin":"monobook","stubthreshold":0,"thumbsize":2,"underline":2,"uselivepreview":0,"usenewrc":0,"watchcreations":0,"watchdefault":0,"watchdeletion":
0,"watchlistdays":3,"watchlisthideanons":0,"watchlisthidebots":0,"watchlisthideliu":0,"watchlisthideminor":0,"watchlisthideown":0,"watchlisthidepatrolled":0,"watchmoves":0,"wllimit":250,"variant":"en","language":"en","searchNs0":true,"searchNs1":false,"searchNs2":false,"searchNs3":false,"searchNs4":false,"searchNs5":false,"searchNs6":false,"searchNs7":false,"searchNs8":false,"searchNs9":false,"searchNs10":false,"searchNs11":false,"searchNs12":false,"searchNs13":false,"searchNs14":false,"searchNs15":false});;},{},{});mw.loader.implement("user.tokens",function($){mw.user.tokens.set({"editToken":"+\\","watchToken":false});;},{},{});

/* cache key: 133099-basin:resourceloader:filter:minify-js:7:74a832f2292f1f4d40d425d223444e78 */
}</script>
<script>if(window.mw){
mw.loader.load(["mediawiki.page.startup","mediawiki.legacy.wikibits","mediawiki.legacy.ajax"]);
}</script><script type="text/javascript" src="./Complete Roguelike Tutorial, using python+libtcod, part 6 - RogueBasin_files/load(2).php"></script>
<style type="text/css">/*<![CDATA[*/
.source-python {line-height: normal;}
.source-python li, .source-python pre {
	line-height: normal; border: 0px none white;
}
/**
 * GeSHi Dynamically Generated Stylesheet
 * --------------------------------------
 * Dynamically generated stylesheet for python
 * CSS class: source-python, CSS id: 
 * GeSHi (C) 2004 - 2007 Nigel McNie, 2007 - 2008 Benny Baumann
 * (http://qbnz.com/highlighter/ and http://geshi.org/)
 * --------------------------------------
 */
.python.source-python .de1, .python.source-python .de2 {font: normal normal 1em/1.2em monospace; margin:0; padding:0; background:none; vertical-align:top;}
.python.source-python  {font-family:monospace;}
.python.source-python .imp {font-weight: bold; color: red;}
.python.source-python li, .python.source-python .li1 {font-weight: normal; vertical-align:top;}
.python.source-python .ln {width:1px;text-align:right;margin:0;padding:0 2px;vertical-align:top;}
.python.source-python .li2 {font-weight: bold; vertical-align:top;}
.python.source-python .kw1 {color: #ff7700;font-weight:bold;}
.python.source-python .kw2 {color: #008000;}
.python.source-python .kw3 {color: #dc143c;}
.python.source-python .kw4 {color: #0000cd;}
.python.source-python .co1 {color: #808080; font-style: italic;}
.python.source-python .coMULTI {color: #808080; font-style: italic;}
.python.source-python .es0 {color: #000099; font-weight: bold;}
.python.source-python .br0 {color: black;}
.python.source-python .sy0 {color: #66cc66;}
.python.source-python .st0 {color: #483d8b;}
.python.source-python .nu0 {color: #ff4500;}
.python.source-python .me1 {color: black;}
.python.source-python .ln-xtra, .python.source-python li.ln-xtra, .python.source-python div.ln-xtra {background-color: #ffc;}
.python.source-python span.xtra { display:block; }

/*]]>*/
</style>
<style type="text/css">/*<![CDATA[*/
@import "/index.php?title=MediaWiki:Geshi.css&usemsgcache=yes&action=raw&ctype=text/css&smaxage=18000";
/*]]>*/
</style></head>
<body class="mediawiki ltr sitedir-ltr ns-0 ns-subject page-Complete_Roguelike_Tutorial_using_python_libtcod_part_6 skin-monobook action-view">
<div id="globalWrapper">
<div id="column-content"><div id="content"><div id="mw-js-message" class="js-messagebox" style="display: none;"></div>
	<a id="top"></a>
	<div id="siteNotice"><div id="localNotice" lang="en" dir="ltr"></div></div>
	<h1 id="firstHeading" class="firstHeading"><span dir="auto">Complete Roguelike Tutorial, using python+libtcod, part 6</span></h1>
	<div id="bodyContent" class="mw-body">
		<div id="siteSub">From RogueBasin</div>
		<div id="contentSub"></div>
		<div id="jump-to-nav" class="mw-jump">Jump to: <a href="http://roguebasin.roguelikedevelopment.org/index.php?title=Complete_Roguelike_Tutorial,_using_python%2Blibtcod,_part_6#column-one">navigation</a>, <a href="http://roguebasin.roguelikedevelopment.org/index.php?title=Complete_Roguelike_Tutorial,_using_python%2Blibtcod,_part_6#searchInput">search</a></div>
		<!-- start content -->
<div id="mw-content-text" lang="en" dir="ltr" class="mw-content-ltr"><center><table border="0" cellpadding="10" cellspacing="0" style="background:#F0E68C"><tbody><tr><td><center>
<p>This is part of a series of tutorials; the main page can be found <a href="http://roguebasin.roguelikedevelopment.org/index.php?title=Complete_Roguelike_Tutorial,_using_python%2Blibtcod" title="Complete Roguelike Tutorial, using python+libtcod">here</a>.
</p><p>The tutorial uses libctod version 1.5.1. If you prefer to use 1.5.0, you can find the old version <a rel="nofollow" class="external text" href="http://roguebasin.roguelikedevelopment.org/index.php?title=Complete_Roguelike_Tutorial,_using_python%2Blibtcod,_part_6&oldid=29871">here</a>
</p>
</center></td></tr></tbody></table></center>
<table id="toc" class="toc"><tbody><tr><td><div id="toctitle"><h2>Contents</h2><span class="toctoggle">&nbsp;[<a href="http://roguebasin.roguelikedevelopment.org/index.php?title=Complete_Roguelike_Tutorial,_using_python%2Blibtcod,_part_6#" class="internal" id="togglelink">hide</a>]&nbsp;</span></div>
<ul>
<li class="toclevel-1"><a href="http://roguebasin.roguelikedevelopment.org/index.php?title=Complete_Roguelike_Tutorial,_using_python%2Blibtcod,_part_6#Going_Berserk.21"><span class="tocnumber">1</span> <span class="toctext"><b>Going Berserk!</b></span></a>
<ul>
<li class="toclevel-2 tocsection-1"><a href="http://roguebasin.roguelikedevelopment.org/index.php?title=Complete_Roguelike_Tutorial,_using_python%2Blibtcod,_part_6#The_components"><span class="tocnumber">1.1</span> <span class="toctext">The components</span></a></li>
<li class="toclevel-2 tocsection-2"><a href="http://roguebasin.roguelikedevelopment.org/index.php?title=Complete_Roguelike_Tutorial,_using_python%2Blibtcod,_part_6#AI"><span class="tocnumber">1.2</span> <span class="toctext">AI</span></a></li>
<li class="toclevel-2 tocsection-3"><a href="http://roguebasin.roguelikedevelopment.org/index.php?title=Complete_Roguelike_Tutorial,_using_python%2Blibtcod,_part_6#Sword-fighting"><span class="tocnumber">1.3</span> <span class="toctext">Sword-fighting</span></a></li>
<li class="toclevel-2 tocsection-4"><a href="http://roguebasin.roguelikedevelopment.org/index.php?title=Complete_Roguelike_Tutorial,_using_python%2Blibtcod,_part_6#Untimely_deaths"><span class="tocnumber">1.4</span> <span class="toctext">Untimely deaths</span></a></li>
</ul>
</li>
</ul>
</td></tr></tbody></table>
<p><br>
</p>
<center><h1> <span class="mw-headline" id="Going_Berserk.21"><b>Going Berserk!</b></span></h1></center>
<p><br>
</p>
<h2> <span class="mw-headline" id="The_components"> The components </span></h2>
<p>Finally, it's time to bash some orc helmets into tiny metal pancakes! Combat is a big turning point in the development of any game: it separates the game from the tech demo. Although dungeon exploration is interesting, the simplest fight can be far more fun, and you may even find yourself playing your game more than you code it!
</p><p>We have a big design decision ahead of us. Until now, the Object class was enough to hold the properties of both the player and the enemies. But as we develop further, many properties will make sense for one kind of Object, but not for another. How do we solve this?
</p><p>Well, we could just pretend that this is not a problem, and use the <b>data-driven</b> approach, which is used by many of the older roguelikes. In this approach, all objects have the same set of properties, and only the values of these properties are modified from object to object. There isn't any feature variation between different objects. For example, there might be a property that determines whether a monster has a petrification attack, another for stealing items or gold, other properties for magical capabilities...
</p><p>As can be seen, it becomes quite tedious to implement a new property for <i>all</i> items every time you want to add a new feature to only <i>one</i>. The only way around this is to limit the number of properties, which in turn limits the number of special features that can be added. This is, of course, not good for us.
</p><p>The other popular alternative is <b>inheritance</b>. You define a hierarchy of parent (a.k.a. base) and child (a.k.a. derived) classes. Child/derived classes (like Item or Monster), in addition to their own properties, receive the properties from their parent classes (such as Object). This reduces redundancy, and there's a seemingly clean separation between different classes.
</p><p>However, the separation is not <i>exactly</i> clean, since the properties of parent classes are 'pasted' on the same space as the child's properties; their properties can conflict if they share names. And there's also the temptation to define deep hierarchies of classes. As you develop further, your hierarchy will grow to extreme lengths (such as Object &gt; Item &gt; Equipment &gt; Weapon &gt; Melee weapon &gt; Blunt weapon &gt; Mace &gt; Legendary Mace of Deep Hierarchies). Each level can add just a tiny bit of functionality over the last one.
</p><p>The fact that a Mace can't be both a Weapon and a Magic Item due to the rigid hierarchy is a bummer. Shuffling classes and code around to achieve these simple tasks is common with inheritance. We want to be able to mix and match freely! Hence, we have inheritance's older, but often forgotten, cousin: <b>composition</b>. It has none of the disadvantages listed above.
</p><p><br>
It's dead simple: there's the Object class, and some component classes. A component class defines extra properties and methods for an Object that needs them. Then you just slap an instance of the component class as a <i>property</i> of the Object; it now "owns" the component. It doesn't even require special functions or code! Let's see how it works.
</p><p><br>
Our first component will be the Fighter. Any object that can fight or be attacked must have it. It holds hit points, maximum hit points (for healing), defense and attack power.
</p><p><br>
</p>
<div style="padding: 5px; border: solid 1px #C0C0C0; background-color: #F0F0F0"><div dir="ltr" class="mw-geshi" style="text-align: left;"><div class="python source-python"><pre class="de1"><span class="kw1">class</span> Fighter:
    <span class="co1">#combat-related properties and methods (monster, player, NPC).</span>
    <span class="kw1">def</span> <span class="kw4">__init__</span><span class="br0">(</span><span class="kw2">self</span>, hp, defense, power<span class="br0">)</span>:
        <span class="kw2">self</span>.<span class="me1">max_hp</span> = hp
        <span class="kw2">self</span>.<span class="me1">hp</span> = hp
        <span class="kw2">self</span>.<span class="me1">defense</span> = defense
        <span class="kw2">self</span>.<span class="me1">power</span> = power</pre></div></div></div>
<p><br>
It'll later be augmented with methods to attack and take damage. 
</p><p>Then there's the BasicMonster component, which holds basic AI routines. You can create other AI components (say, for ranged combat) and use them for some monsters. We'll define a <i>take_turn</i> method; as long as a component defines this method, it's a valid alternative to BasicMonster. For now it just prints a debug message:
</p><p><br>
</p>
<div style="padding: 5px; border: solid 1px #C0C0C0; background-color: #F0F0F0"><div dir="ltr" class="mw-geshi" style="text-align: left;"><div class="python source-python"><pre class="de1"><span class="kw1">class</span> BasicMonster:
    <span class="co1">#AI for a basic monster.</span>
    <span class="kw1">def</span> take_turn<span class="br0">(</span><span class="kw2">self</span><span class="br0">)</span>:
        <span class="kw1">print</span> <span class="st0">'The '</span> + <span class="kw2">self</span>.<span class="me1">owner</span>.<span class="me1">name</span> + <span class="st0">' growls!'</span></pre></div></div></div>
<p><br>
Ignore the reference to <i>self.owner</i> -- it's just the Object instance that owns this component, and is initialized elsewhere. We'll get to that in a moment. So how do we associate components with an Object? It's simple: create a Fighter instance, and/or a BasicMonster instance, and pass them as parameters when initializing the Object:
</p><p><br>
</p>
<div style="padding: 5px; border: solid 1px #C0C0C0; background-color: #F0F0F0"><div dir="ltr" class="mw-geshi" style="text-align: left;"><div class="python source-python"><pre class="de1">    <span class="kw1">def</span> <span class="kw4">__init__</span><span class="br0">(</span><span class="kw2">self</span>, x, y, char, name, color, blocks=<span class="kw2">False</span>, fighter=<span class="kw2">None</span>, ai=<span class="kw2">None</span><span class="br0">)</span>:</pre></div></div></div>
<p><br>
Notice that all components are optional; they can be <i>None</i> if you don't want them. Then they're stored as properties of the object, for example with <i>self.fighter = fighter</i>. Also, since a component will often want to deal with its owner Object, it has to "know" who it is (for example, to get its position, or its name -- as you noticed earlier, <i>BasicMonster</i> 's <i>take_turn</i> method needs to know the object's name to display a proper message). So, in addition to holding the component, the Object will set the component's <i>owner</i> property to itself. The <i>if</i> lines just make sure this happens only if the component is actually defined.
</p><p><br>
</p>
<div style="padding: 5px; border: solid 1px #C0C0C0; background-color: #F0F0F0"><div dir="ltr" class="mw-geshi" style="text-align: left;"><div class="python source-python"><pre class="de1">        <span class="kw2">self</span>.<span class="me1">fighter</span> = fighter
        <span class="kw1">if</span> <span class="kw2">self</span>.<span class="me1">fighter</span>:  <span class="co1">#let the fighter component know who owns it</span>
            <span class="kw2">self</span>.<span class="me1">fighter</span>.<span class="me1">owner</span> = <span class="kw2">self</span>
&nbsp;
        <span class="kw2">self</span>.<span class="me1">ai</span> = ai
        <span class="kw1">if</span> <span class="kw2">self</span>.<span class="me1">ai</span>:  <span class="co1">#let the AI component know who owns it</span>
            <span class="kw2">self</span>.<span class="me1">ai</span>.<span class="me1">owner</span> = <span class="kw2">self</span></pre></div></div></div>
<p><br>
This may look a bit weird, but now we can follow these properties around to go from a component (<i>self</i>), to its owner object (<i>self.owner</i>), to a different one of its components (<i>self.owner.ai</i>), allowing us to do all sorts of funky stuff! Most other systems don't have this kind of flexibility for free. This is actually the most complicated code that composition needs; the rest will be pure game logic!
</p><p>OK, now it's time to decide on some stats for the monsters and the player! First up, the player. Just create a Fighter component with the stats you choose, and set it as the <i>fighter</i> parameter when creating the player object. Place it above the main loop:
</p><p><br>
</p>
<div style="padding: 5px; border: solid 1px #C0C0C0; background-color: #F0F0F0"><div dir="ltr" class="mw-geshi" style="text-align: left;"><div class="python source-python"><pre class="de1"><span class="co1">#create object representing the player</span>
fighter_component = Fighter<span class="br0">(</span>hp=<span class="nu0">30</span>, defense=<span class="nu0">2</span>, power=<span class="nu0">5</span><span class="br0">)</span>
player = Object<span class="br0">(</span><span class="nu0">0</span>, <span class="nu0">0</span>, <span class="st0">'@'</span>, <span class="st0">'player'</span>, libtcod.<span class="me1">white</span>, blocks=<span class="kw2">True</span>, fighter=fighter_component<span class="br0">)</span></pre></div></div></div>
<p><br>
Here, I decided to use <a rel="nofollow" class="external text" href="http://docs.python.org/tutorial/controlflow.html#keyword-arguments">keyword arguments</a> to make it clear what the different stats are (<i>Fighter(30, 2, 5)</i> is hard to interpret). They're not necessary for the first few arguments of <i>Object</i> since you can easily deduce what they mean (name, color, etc). This is common sense for most people, but I'll say it anyway: always try to strike a good balance between short and readable code; in places where you can't, pepper it with lots explanatory comments. It will make your code much easier to maintain!
</p><p>Now, the monsters are defined in <i>place_objects</i>. Trolls will be obviously stronger than orcs. Monsters have two components: Fighter and BasicMonster.
</p><p><br>
</p>
<div style="padding: 5px; border: solid 1px #C0C0C0; background-color: #F0F0F0"><div dir="ltr" class="mw-geshi" style="text-align: left;"><div class="python source-python"><pre class="de1">                <span class="co1">#create an orc</span>
                fighter_component = Fighter<span class="br0">(</span>hp=<span class="nu0">10</span>, defense=<span class="nu0">0</span>, power=<span class="nu0">3</span><span class="br0">)</span>
                ai_component = BasicMonster<span class="br0">(</span><span class="br0">)</span>
&nbsp;
                monster = Object<span class="br0">(</span>x, y, <span class="st0">'o'</span>, <span class="st0">'orc'</span>, libtcod.<span class="me1">desaturated_green</span>,
                    blocks=<span class="kw2">True</span>, fighter=fighter_component, ai=ai_component<span class="br0">)</span>
            <span class="kw1">else</span>:
                <span class="co1">#create a troll</span>
                fighter_component = Fighter<span class="br0">(</span>hp=<span class="nu0">16</span>, defense=<span class="nu0">1</span>, power=<span class="nu0">4</span><span class="br0">)</span>
                ai_component = BasicMonster<span class="br0">(</span><span class="br0">)</span>
&nbsp;
                monster = Object<span class="br0">(</span>x, y, <span class="st0">'T'</span>, <span class="st0">'troll'</span>, libtcod.<span class="me1">darker_green</span>,
                    blocks=<span class="kw2">True</span>, fighter=fighter_component, ai=ai_component<span class="br0">)</span></pre></div></div></div>
<p><br>
Keyword arguments come to the rescue again, since in the future most objects will have only a handful of all possible components. This way you can set only the ones you want, even if they're out-of-order!
</p>
<h2> <span class="mw-headline" id="AI"> AI </span></h2>
<p>It's time to make our monsters move and kick about! It's not really "artificial intelligence", as these guys will be pretty thick. The rule for them is: if you see the player, chase him. Actually, we'll assume that the monster can see the player if its within the player's FOV.
</p><p>We'll create a chasing method (<i>move_towards</i>) in the Object class, which can be used to simplify all your AI functions. It has a bit of vector mathematics, but if you're not into that you can use it without understanding how it works. Basically, we get a vector from the object to the target, then we normalize it so it has the same <i>direction</i> but has a length of exactly 1 tile, and then we round it so the resulting vector is integer (instead of fractional as usual - so dx and dy can only take the values 0, -1 or +1). The object then moves by this amount. Of course, you don't have to understand the math thoroughly in order to use it!
</p><p><br>
</p>
<div style="padding: 5px; border: solid 1px #C0C0C0; background-color: #F0F0F0"><div dir="ltr" class="mw-geshi" style="text-align: left;"><div class="python source-python"><pre class="de1">    <span class="kw1">def</span> move_towards<span class="br0">(</span><span class="kw2">self</span>, target_x, target_y<span class="br0">)</span>:
        <span class="co1">#vector from this object to the target, and distance</span>
        dx = target_x - <span class="kw2">self</span>.<span class="me1">x</span>
        dy = target_y - <span class="kw2">self</span>.<span class="me1">y</span>
        distance = <span class="kw3">math</span>.<span class="me1">sqrt</span><span class="br0">(</span>dx <span class="sy0">**</span> <span class="nu0">2</span> + dy <span class="sy0">**</span> <span class="nu0">2</span><span class="br0">)</span>
&nbsp;
        <span class="co1">#normalize it to length 1 (preserving direction), then round it and</span>
        <span class="co1">#convert to integer so the movement is restricted to the map grid</span>
        dx = <span class="kw2">int</span><span class="br0">(</span><span class="kw2">round</span><span class="br0">(</span>dx / distance<span class="br0">)</span><span class="br0">)</span>
        dy = <span class="kw2">int</span><span class="br0">(</span><span class="kw2">round</span><span class="br0">(</span>dy / distance<span class="br0">)</span><span class="br0">)</span>
        <span class="kw2">self</span>.<span class="me1">move</span><span class="br0">(</span>dx, dy<span class="br0">)</span></pre></div></div></div>
<p><br>
Another useful Object method returns the distance between two objects, using the common distance formula. You need <i>import math</i> at the top of the file in order to use the square root function.
</p><p><br>
</p>
<div style="padding: 5px; border: solid 1px #C0C0C0; background-color: #F0F0F0"><div dir="ltr" class="mw-geshi" style="text-align: left;"><div class="python source-python"><pre class="de1">    <span class="kw1">def</span> distance_to<span class="br0">(</span><span class="kw2">self</span>, other<span class="br0">)</span>:
        <span class="co1">#return the distance to another object</span>
        dx = other.<span class="me1">x</span> - <span class="kw2">self</span>.<span class="me1">x</span>
        dy = other.<span class="me1">y</span> - <span class="kw2">self</span>.<span class="me1">y</span>
        <span class="kw1">return</span> <span class="kw3">math</span>.<span class="me1">sqrt</span><span class="br0">(</span>dx <span class="sy0">**</span> <span class="nu0">2</span> + dy <span class="sy0">**</span> <span class="nu0">2</span><span class="br0">)</span></pre></div></div></div>
<p><br>
As mentioned earlier, the behavior is simply "if you see the player, chase him". Here's the full code for the BasicMonster class that does it. The monster is only active if its within the player's FOV.
</p><p><br>
</p>
<div style="padding: 5px; border: solid 1px #C0C0C0; background-color: #F0F0F0"><div dir="ltr" class="mw-geshi" style="text-align: left;"><div class="python source-python"><pre class="de1"><span class="kw1">class</span> BasicMonster:
    <span class="co1">#AI for a basic monster.</span>
    <span class="kw1">def</span> take_turn<span class="br0">(</span><span class="kw2">self</span><span class="br0">)</span>:
        <span class="co1">#a basic monster takes its turn. If you can see it, it can see you</span>
        monster = <span class="kw2">self</span>.<span class="me1">owner</span>
        <span class="kw1">if</span> libtcod.<span class="me1">map_is_in_fov</span><span class="br0">(</span>fov_map, monster.<span class="me1">x</span>, monster.<span class="me1">y</span><span class="br0">)</span>:
&nbsp;
            <span class="co1">#move towards player if far away</span>
            <span class="kw1">if</span> monster.<span class="me1">distance_to</span><span class="br0">(</span>player<span class="br0">)</span> <span class="sy0">&gt;</span>= <span class="nu0">2</span>:
                monster.<span class="me1">move_towards</span><span class="br0">(</span>player.<span class="me1">x</span>, player.<span class="me1">y</span><span class="br0">)</span>
&nbsp;
            <span class="co1">#close enough, attack! (if the player is still alive.)</span>
            <span class="kw1">elif</span> player.<span class="me1">fighter</span>.<span class="me1">hp</span> <span class="sy0">&gt;</span> <span class="nu0">0</span>:
                <span class="kw1">print</span> <span class="st0">'The attack of the '</span> + monster.<span class="me1">name</span> + <span class="st0">' bounces off your shiny metal armor!'</span></pre></div></div></div>
<p><br>
That's not terribly smart, but it gets the job done! You can, of course, improve it a lot; for now we'll just leave it like this and continue working on combat. The last thing is to call <i>take_turn</i> for any intelligent monsters from the main loop:
</p><p><br>
</p>
<div style="padding: 5px; border: solid 1px #C0C0C0; background-color: #F0F0F0"><div dir="ltr" class="mw-geshi" style="text-align: left;"><div class="python source-python"><pre class="de1">    <span class="kw1">if</span> game_state == <span class="st0">'playing'</span> <span class="kw1">and</span> player_action <span class="sy0">!</span>= <span class="st0">'didnt-take-turn'</span>:
        <span class="kw1">for</span> <span class="kw2">object</span> <span class="kw1">in</span> objects:
            <span class="kw1">if</span> <span class="kw2">object</span>.<span class="me1">ai</span>:
                <span class="kw2">object</span>.<span class="me1">ai</span>.<span class="me1">take_turn</span><span class="br0">(</span><span class="br0">)</span></pre></div></div></div>
<p><br>
Ready to test! The annoying little buggers will now chase you and try to hit you.
</p><p>The whole code is available <a href="http://roguebasin.roguelikedevelopment.org/index.php?title=Complete_Roguelike_Tutorial,_using_python%2Blibtcod,_part_6_code" title="Complete Roguelike Tutorial, using python+libtcod, part 6 code">here</a>.
</p><p><br>
</p>
<h2> <span class="mw-headline" id="Sword-fighting"> Sword-fighting </span></h2>
<p>The quest for some epic medieval combat is coming to an end! We will now write the actual functions to attack and take damage, and replace those silly placeholders with the meaty stuff.
</p><p>The "meaty stuff" is deliberately simple. This is so you can easily change it with your own damage system, whatever it may be. The <i>Fighter</i> class will have a method to take damage:
</p><p><br>
</p>
<div style="padding: 5px; border: solid 1px #C0C0C0; background-color: #F0F0F0"><div dir="ltr" class="mw-geshi" style="text-align: left;"><div class="python source-python"><pre class="de1">    <span class="kw1">def</span> take_damage<span class="br0">(</span><span class="kw2">self</span>, damage<span class="br0">)</span>:
        <span class="co1">#apply damage if possible</span>
        <span class="kw1">if</span> damage <span class="sy0">&gt;</span> <span class="nu0">0</span>:
            <span class="kw2">self</span>.<span class="me1">hp</span> -= damage</pre></div></div></div>
<p><br>
In the next section we'll modify it to also handle deaths. Then there's the method to attack another object:
</p><p><br>
</p>
<div style="padding: 5px; border: solid 1px #C0C0C0; background-color: #F0F0F0"><div dir="ltr" class="mw-geshi" style="text-align: left;"><div class="python source-python"><pre class="de1">    <span class="kw1">def</span> attack<span class="br0">(</span><span class="kw2">self</span>, target<span class="br0">)</span>:
        <span class="co1">#a simple formula for attack damage</span>
        damage = <span class="kw2">self</span>.<span class="me1">power</span> - target.<span class="me1">fighter</span>.<span class="me1">defense</span>
&nbsp;
        <span class="kw1">if</span> damage <span class="sy0">&gt;</span> <span class="nu0">0</span>:
            <span class="co1">#make the target take some damage</span>
            <span class="kw1">print</span> <span class="kw2">self</span>.<span class="me1">owner</span>.<span class="me1">name</span>.<span class="me1">capitalize</span><span class="br0">(</span><span class="br0">)</span> + <span class="st0">' attacks '</span> + target.<span class="me1">name</span> + <span class="st0">' for '</span> + <span class="kw2">str</span><span class="br0">(</span>damage<span class="br0">)</span> + <span class="st0">' hit points.'</span>
            target.<span class="me1">fighter</span>.<span class="me1">take_damage</span><span class="br0">(</span>damage<span class="br0">)</span>
        <span class="kw1">else</span>:
            <span class="kw1">print</span> <span class="kw2">self</span>.<span class="me1">owner</span>.<span class="me1">name</span>.<span class="me1">capitalize</span><span class="br0">(</span><span class="br0">)</span> + <span class="st0">' attacks '</span> + target.<span class="me1">name</span> + <span class="st0">' but it has no effect!'</span></pre></div></div></div>
<p><br>
It calls the previous method in order to handle taking damage. We separated "attacks" and "damage" because you might want an event, like poison or a trap, to directly damage an object by some amount, without going through the attack damage formula.
</p><p>Now to give them some use. In the <i>BasicMonster</i> 's <i>take_turn</i> method, replace the dummy <i>print</i> line for the monster's attack with:
</p><p><br>
</p>
<div style="padding: 5px; border: solid 1px #C0C0C0; background-color: #F0F0F0"><div dir="ltr" class="mw-geshi" style="text-align: left;"><div class="python source-python"><pre class="de1">                monster.<span class="me1">fighter</span>.<span class="me1">attack</span><span class="br0">(</span>player<span class="br0">)</span></pre></div></div></div>
<p><br>
And the dummy <i>print</i> line for the player's attack, in <i>player_move_or_attack</i>, with:
</p><p><br>
</p>
<div style="padding: 5px; border: solid 1px #C0C0C0; background-color: #F0F0F0"><div dir="ltr" class="mw-geshi" style="text-align: left;"><div class="python source-python"><pre class="de1">        player.<span class="me1">fighter</span>.<span class="me1">attack</span><span class="br0">(</span>target<span class="br0">)</span></pre></div></div></div>
<p><br>
That's it, the player and the monsters can beat each other silly, but no-one will die. We'll take this opportunity to print the player's HP so you can see it plummeting to negative values as the monsters attack you. This is how you make a simple GUI! At the end of the <i>render_all</i> function:
</p><p><br>
</p>
<div style="padding: 5px; border: solid 1px #C0C0C0; background-color: #F0F0F0"><div dir="ltr" class="mw-geshi" style="text-align: left;"><div class="python source-python"><pre class="de1">    <span class="co1">#show the player's stats</span>
    libtcod.<span class="me1">console_set_default_foreground</span><span class="br0">(</span>con, libtcod.<span class="me1">white</span><span class="br0">)</span>
    libtcod.<span class="me1">console_print_ex</span><span class="br0">(</span><span class="nu0">0</span>, <span class="nu0">1</span>, SCREEN_HEIGHT - <span class="nu0">2</span>, libtcod.<span class="me1">BKGND_NONE</span>, libtcod.<span class="me1">LEFT</span>,
        <span class="st0">'HP: '</span> + <span class="kw2">str</span><span class="br0">(</span>player.<span class="me1">fighter</span>.<span class="me1">hp</span><span class="br0">)</span> + <span class="st0">'/'</span> + <span class="kw2">str</span><span class="br0">(</span>player.<span class="me1">fighter</span>.<span class="me1">max_hp</span><span class="br0">)</span><span class="br0">)</span></pre></div></div></div>
<p><br>
</p>
<h2> <span class="mw-headline" id="Untimely_deaths"> Untimely deaths </span></h2>
<p>Of course, nobody can lose HP indefinitely. We'll now code the inevitable demise of both the monsters and the player! This is handled by the Fighter class. Since different objects have different behaviors when killed, the Fighter class must know what function to call when the object dies. This is so that monsters leave corpses behind, the player loses the game, the end-level boss reveals the stairs to the next level, etc. This <i>death_function</i> is passed as a parameter when creating a Fighter instance.
</p><p><br>
</p>
<div style="padding: 5px; border: solid 1px #C0C0C0; background-color: #F0F0F0"><div dir="ltr" class="mw-geshi" style="text-align: left;"><div class="python source-python"><pre class="de1">    <span class="kw1">def</span> <span class="kw4">__init__</span><span class="br0">(</span><span class="kw2">self</span>, hp, defense, power, death_function=<span class="kw2">None</span><span class="br0">)</span>:
        <span class="kw2">self</span>.<span class="me1">death_function</span> = death_function</pre></div></div></div>
<p><br>
It is then called by the <i>take_damage</i> method, in the event that the HP reaches 0:
</p><p><br>
</p>
<div style="padding: 5px; border: solid 1px #C0C0C0; background-color: #F0F0F0"><div dir="ltr" class="mw-geshi" style="text-align: left;"><div class="python source-python"><pre class="de1">            <span class="co1">#check for death. if there's a death function, call it</span>
            <span class="kw1">if</span> <span class="kw2">self</span>.<span class="me1">hp</span> <span class="sy0">&lt;</span>= <span class="nu0">0</span>:
                function = <span class="kw2">self</span>.<span class="me1">death_function</span>
                <span class="kw1">if</span> function <span class="kw1">is</span> <span class="kw1">not</span> <span class="kw2">None</span>:
                    function<span class="br0">(</span><span class="kw2">self</span>.<span class="me1">owner</span><span class="br0">)</span></pre></div></div></div>
<p><br>
Now we'll define some fun death functions! They just change the object so it looks like a corpse, as well as printing some messages. The player's death also changes the game state, so he can't move or attack any more.
</p><p><br>
</p>
<div style="padding: 5px; border: solid 1px #C0C0C0; background-color: #F0F0F0"><div dir="ltr" class="mw-geshi" style="text-align: left;"><div class="python source-python"><pre class="de1"><span class="kw1">def</span> player_death<span class="br0">(</span>player<span class="br0">)</span>:
    <span class="co1">#the game ended!</span>
    <span class="kw1">global</span> game_state
    <span class="kw1">print</span> <span class="st0">'You died!'</span>
    game_state = <span class="st0">'dead'</span>
&nbsp;
    <span class="co1">#for added effect, transform the player into a corpse!</span>
    player.<span class="me1">char</span> = <span class="st0">'%'</span>
    player.<span class="me1">color</span> = libtcod.<span class="me1">dark_red</span>
&nbsp;
<span class="kw1">def</span> monster_death<span class="br0">(</span>monster<span class="br0">)</span>:
    <span class="co1">#transform it into a nasty corpse! it doesn't block, can't be</span>
    <span class="co1">#attacked and doesn't move</span>
    <span class="kw1">print</span> monster.<span class="me1">name</span>.<span class="me1">capitalize</span><span class="br0">(</span><span class="br0">)</span> + <span class="st0">' is dead!'</span>
    monster.<span class="me1">char</span> = <span class="st0">'%'</span>
    monster.<span class="me1">color</span> = libtcod.<span class="me1">dark_red</span>
    monster.<span class="me1">blocks</span> = <span class="kw2">False</span>
    monster.<span class="me1">fighter</span> = <span class="kw2">None</span>
    monster.<span class="me1">ai</span> = <span class="kw2">None</span>
    monster.<span class="me1">name</span> = <span class="st0">'remains of '</span> + monster.<span class="me1">name</span></pre></div></div></div>
<p><br>
Notice that the monster's components were disabled, so it doesn't run any AI functions and can no longer be attacked.
</p><p>To assign these behaviours to the player and monsters, pass the extra parameter <i>death_function=monster_death</i> when creating the monsters' Fighter component, in <i>place_objects</i>; and also when creating the player's Fighter component before the main loop (<i>death_function=player_death</i>).
</p><p>We'll add a few details to polish it up. For the impatient, however: it's ready to play now! You may notice some glitches though. In <i>player_move_or_attack</i>, we only want the player to attack objects that have a Fighter component. So change the <i>if object.x == x ...</i> line to:
</p><p><br>
</p>
<div style="padding: 5px; border: solid 1px #C0C0C0; background-color: #F0F0F0"><div dir="ltr" class="mw-geshi" style="text-align: left;"><div class="python source-python"><pre class="de1">        <span class="kw1">if</span> <span class="kw2">object</span>.<span class="me1">fighter</span> <span class="kw1">and</span> <span class="kw2">object</span>.<span class="me1">x</span> == x <span class="kw1">and</span> <span class="kw2">object</span>.<span class="me1">y</span> == y:</pre></div></div></div>
<p><br>
There's also currently the issue that, when the player walks over a corpse, sometimes it's drawn over the player! There's no guarantee that the player is the object that is drawn last. So we need to draw all other objects first, and only then the player. Just change the rendering loop in <i>render_all</i> to:
</p><p><br>
</p>
<div style="padding: 5px; border: solid 1px #C0C0C0; background-color: #F0F0F0"><div dir="ltr" class="mw-geshi" style="text-align: left;"><div class="python source-python"><pre class="de1">    <span class="co1">#draw all objects in the list, except the player. we want it to</span>
    <span class="co1">#always appear over all other objects! so it's drawn later.</span>
    <span class="kw1">for</span> <span class="kw2">object</span> <span class="kw1">in</span> objects:
        <span class="kw1">if</span> <span class="kw2">object</span> <span class="sy0">!</span>= player:
            <span class="kw2">object</span>.<span class="me1">draw</span><span class="br0">(</span><span class="br0">)</span>
    player.<span class="me1">draw</span><span class="br0">(</span><span class="br0">)</span></pre></div></div></div>
<p><br>
The same thing also happens with monsters -- a monster corpse being drawn over another monster. To fix it, create a method in the <i>Object</i> class that moves it to the start of the list, so it's drawn first:
</p><p><br>
</p>
<div style="padding: 5px; border: solid 1px #C0C0C0; background-color: #F0F0F0"><div dir="ltr" class="mw-geshi" style="text-align: left;"><div class="python source-python"><pre class="de1">    <span class="kw1">def</span> send_to_back<span class="br0">(</span><span class="kw2">self</span><span class="br0">)</span>:
        <span class="co1">#make this object be drawn first, so all others appear above it if they're in the same tile.</span>
        <span class="kw1">global</span> objects
        objects.<span class="me1">remove</span><span class="br0">(</span><span class="kw2">self</span><span class="br0">)</span>
        objects.<span class="me1">insert</span><span class="br0">(</span><span class="nu0">0</span>, <span class="kw2">self</span><span class="br0">)</span></pre></div></div></div>
<p><br>
And call it somewhere in the <i>monster_death</i> function:
</p><p><br>
</p>
<div style="padding: 5px; border: solid 1px #C0C0C0; background-color: #F0F0F0"><div dir="ltr" class="mw-geshi" style="text-align: left;"><div class="python source-python"><pre class="de1">    monster.<span class="me1">send_to_back</span><span class="br0">(</span><span class="br0">)</span></pre></div></div></div>
<p><br>
It's finally ready to play, and it actually feels like a game! It was a long journey since we first printed the @ character, but we've got random dungeons, FOV, exploration, enemies, AI, and a true combat system. You can now beat those pesky monsters into a pulp and walk over them! (Ugh!) See if you can finish off all of them before they do the same to you.
</p><p>You may have noticed that this is fine and dandy for a turn-based game, but in a real-time game the monsters are just too fast! If that happens to be the case with your game, <a href="http://roguebasin.roguelikedevelopment.org/index.php?title=Complete_Roguelike_Tutorial,_using_Python%2Blibtcod,_extras#Real-time_combat" title="Complete Roguelike Tutorial, using Python+libtcod, extras">check out this Extra</a> on real-time combat.
</p><p><br>
The whole code is available <a href="http://roguebasin.roguelikedevelopment.org/index.php?title=Complete_Roguelike_Tutorial,_using_python%2Blibtcod,_part_6_code#Untimely_deaths" title="Complete Roguelike Tutorial, using python+libtcod, part 6 code">here</a>.
</p><p><a href="http://roguebasin.roguelikedevelopment.org/index.php?title=Complete_Roguelike_Tutorial,_using_python%2Blibtcod,_part_7" title="Complete Roguelike Tutorial, using python+libtcod, part 7">Go on to the next part</a>.
</p>
<!-- 
NewPP limit report
Preprocessor node count: 239/1000000
Post-expand include size: 0/2097152 bytes
Template argument size: 0/2097152 bytes
Expensive parser function count: 0/100
-->

<!-- Saved in parser cache with key 133099-basin:pcache:idhash:3806-0!*!0!!en!*!* and timestamp 20131214123135 -->
</div><div class="printfooter">
Retrieved from "<a href="http://roguebasin.roguelikedevelopment.org/index.php?title=Complete_Roguelike_Tutorial,_using_python%2Blibtcod,_part_6&oldid=30253">http://roguebasin.roguelikedevelopment.org/index.php?title=Complete_Roguelike_Tutorial,_using_python%2Blibtcod,_part_6&amp;oldid=30253</a>"</div>
		<div id="catlinks" class="catlinks"><div id="mw-normal-catlinks" class="mw-normal-catlinks"><a href="http://roguebasin.roguelikedevelopment.org/index.php?title=Special:Categories" title="Special:Categories">Category</a>: <ul><li><a href="http://roguebasin.roguelikedevelopment.org/index.php?title=Category:Developing" title="Category:Developing">Developing</a></li></ul></div></div>		<!-- end content -->
				<div class="visualClear"></div>
	</div>
</div></div>
<div id="column-one">
	<div id="p-cactions" class="portlet">
		<h5>Views</h5>
		<div class="pBody">
			<ul>
				<li id="ca-nstab-main" class="selected"><a href="./Complete Roguelike Tutorial, using python+libtcod, part 6 - RogueBasin_files/Complete Roguelike Tutorial, using python+libtcod, part 6 - RogueBasin.html" primary="1" context="subject" title="View the content page [alt-c]" accesskey="c">Page</a></li>
				<li id="ca-talk"><a href="http://roguebasin.roguelikedevelopment.org/index.php?title=Talk:Complete_Roguelike_Tutorial,_using_python%2Blibtcod,_part_6" primary="1" context="talk" title="Discussion about the content page [alt-t]" accesskey="t">Discussion</a></li>
				<li id="ca-viewsource"><a href="http://roguebasin.roguelikedevelopment.org/index.php?title=Complete_Roguelike_Tutorial,_using_python%2Blibtcod,_part_6&action=edit" primary="1" title="This page is protected.
You can view its source [alt-e]" accesskey="e">View source</a></li>
				<li id="ca-history"><a href="http://roguebasin.roguelikedevelopment.org/index.php?title=Complete_Roguelike_Tutorial,_using_python%2Blibtcod,_part_6&action=history" rel="archives" title="Past revisions of this page [alt-h]" accesskey="h">History</a></li>
			</ul>
		</div>
	</div>
	<div class="portlet" id="p-personal">
		<h5>Personal tools</h5>
		<div class="pBody">
			<ul>
				<li id="pt-login"><a href="http://roguebasin.roguelikedevelopment.org/index.php?title=Special:UserLogin&returnto=Complete+Roguelike+Tutorial%2C+using+python%2Blibtcod%2C+part+6" title="You are encouraged to log in; however, it is not mandatory [alt-o]" accesskey="o">Log in / create account</a></li>
			</ul>
		</div>
	</div>
	<div class="portlet" id="p-logo">
<a href="http://roguebasin.roguelikedevelopment.org/index.php?title=Main_Page" style="background-image: url(/skins/roguebasin/RogueBasin_logo.png);" title="Visit the main page"></a>
	</div>
	<div class="generated-sidebar portlet" id="p-navigation">
		<h5>Navigation</h5>
		<div class="pBody">
			<ul>
				<li id="n-mainpage"><a href="http://roguebasin.roguelikedevelopment.org/index.php?title=Main_Page" title="Visit the main page [alt-z]" accesskey="z">Main Page</a></li>
				<li id="n-portal"><a href="http://roguebasin.roguelikedevelopment.org/index.php?title=RogueBasin:Community_portal" title="About the project, what you can do, where to find things">Community portal</a></li>
				<li id="n-recentchanges"><a href="http://roguebasin.roguelikedevelopment.org/index.php?title=Special:RecentChanges" title="A list of recent changes in the wiki [alt-r]" accesskey="r">Recent changes</a></li>
				<li id="n-randompage"><a href="http://roguebasin.roguelikedevelopment.org/index.php?title=Special:Random" title="Load a random page [alt-x]" accesskey="x">Random page</a></li>
				<li id="n-help"><a href="http://roguebasin.roguelikedevelopment.org/index.php?title=Help" title="The place to find out">Help</a></li>
			</ul>
		</div>
	</div>
	<div id="p-search" class="portlet">
		<h5><label for="searchInput">Search</label></h5>
		<div id="searchBody" class="pBody">
			<form action="http://roguebasin.roguelikedevelopment.org/index.php" id="searchform">
				<input type="hidden" name="title" value="Special:Search">
				<input type="search" name="search" title="Search RogueBasin [alt-f]" accesskey="f" id="searchInput">
				<input type="submit" name="go" value="Go" title="Go to a page with this exact name if exists" id="searchGoButton" class="searchButton">&nbsp;
				<input type="submit" name="fulltext" value="Search" title="Search the pages for this text" id="mw-searchButton" class="searchButton">
			</form>
		</div>
	</div>
	<div class="portlet" id="p-tb">
		<h5>Toolbox</h5>
		<div class="pBody">
			<ul>
				<li id="t-whatlinkshere"><a href="http://roguebasin.roguelikedevelopment.org/index.php?title=Special:WhatLinksHere/Complete_Roguelike_Tutorial,_using_python%2Blibtcod,_part_6" title="A list of all wiki pages that link here [alt-j]" accesskey="j">What links here</a></li>
				<li id="t-recentchangeslinked"><a href="http://roguebasin.roguelikedevelopment.org/index.php?title=Special:RecentChangesLinked/Complete_Roguelike_Tutorial,_using_python%2Blibtcod,_part_6" title="Recent changes in pages linked from this page [alt-k]" accesskey="k">Related changes</a></li>
				<li id="t-specialpages"><a href="http://roguebasin.roguelikedevelopment.org/index.php?title=Special:SpecialPages" title="A list of all special pages [alt-q]" accesskey="q">Special pages</a></li>
				<li><a href="http://roguebasin.roguelikedevelopment.org/index.php?title=Complete_Roguelike_Tutorial,_using_python%2Blibtcod,_part_6&printable=yes" rel="alternate">Printable version</a></li>
				<li id="t-permalink"><a href="http://roguebasin.roguelikedevelopment.org/index.php?title=Complete_Roguelike_Tutorial,_using_python%2Blibtcod,_part_6&oldid=30253" title="Permanent link to this revision of the page">Permanent link</a></li>
			</ul>
		</div>
	</div>
</div><!-- end of the left (by default at least) column -->
<div class="visualClear"></div>
<div id="footer">
	<div id="f-poweredbyico">
		<a href="http://www.mediawiki.org/"><img src="./Complete Roguelike Tutorial, using python+libtcod, part 6 - RogueBasin_files/poweredby_mediawiki_88x31.png" alt="Powered by MediaWiki" width="88" height="31"></a>
	</div>
	<ul id="f-list">
		<li id="lastmod"> This page was last modified on 13 November 2012, at 04:58.</li>
		<li id="viewcount">This page has been accessed 14,428 times.</li>
		<li id="privacy"><a href="http://roguebasin.roguelikedevelopment.org/index.php?title=RogueBasin:Privacy_policy" title="RogueBasin:Privacy policy">Privacy policy</a></li>
		<li id="about"><a href="http://roguebasin.roguelikedevelopment.org/index.php?title=RogueBasin:About" title="RogueBasin:About">About RogueBasin</a></li>
		<li id="disclaimer"><a href="http://roguebasin.roguelikedevelopment.org/index.php?title=RogueBasin:General_disclaimer" title="RogueBasin:General disclaimer">Disclaimers</a></li>
	</ul>
</div>
</div>
<script>if(window.mw){
mw.loader.load(["mediawiki.user","mediawiki.page.ready"], null, true);
}</script><script src="./Complete Roguelike Tutorial, using python+libtcod, part 6 - RogueBasin_files/load(3).php" type="text/javascript"></script>
<script src="./Complete Roguelike Tutorial, using python+libtcod, part 6 - RogueBasin_files/load(4).php"></script>
<!-- Served in 0.181 secs. --><autoscroll_cursor hidden=""></autoscroll_cursor></body></html>